﻿// <copyright file="RecentBills.cs" company="Microsoft Corporation">
// Copyright (c) 2009 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2009-05-29</date>
// <summary>RecentBills class definition</summary>

namespace NYTimes
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Linq;
    using System.Xml.Linq;
    using NYTimes.Core;
    using NYTimes.Data;

    /// <summary>
    /// When type = introduced, the introduced_date determines the set of recent bills. 
    /// When type = updated, the latest_major_action_date determines the result set. See the sample 
    /// responses for examples of bill summary data.
    /// </summary>
    public enum BillType
    {
        /// <summary>
        /// the introduced_date determines the set of recent bills. 
        /// </summary>
        Introduced,

        /// <summary>
        /// the latest_major_action_date determines the result set
        /// </summary>
        Updated
    }

    /// <summary>
    /// New York Times US Congress Recent Bills API
    /// </summary>
    /// <remarks>For more information, see 
    /// <a href="http://developer.nytimes.com/docs/congress_api#h3-bills">this article</a>.</remarks>
    public class RecentBills : CongressApi
    {
        #region Fields
        /// <summary>
        /// The chamber (House or Senate)
        /// </summary>
        private Chamber chamber;

        /// <summary>
        /// The congress number 
        /// </summary>
        private int congressNumber;

        /// <summary>
        /// The bill type
        /// </summary>
        private BillType billType;

        #endregion

        /// <summary>
        /// Initializes a new instance of the RecentBills class.
        /// </summary>
        public RecentBills()
        {
            this.Bills = new ObservableCollection<Bill>();

            if (SampleData.IsInDesignTool)
            {
                var xml = Core.SampleData.GetSampleData("introduced.xml");

                if (!string.IsNullOrEmpty(xml))
                {
                    this.ParseXml(xml);
                }
            }
        }

        #region Properties
        /// <summary>
        /// Gets or sets the chamber (House or Senate)
        /// </summary>
        public Chamber Chamber
        {
            get
            {
                return this.chamber;
            }

            set
            {
                if (this.chamber != value)
                {
                    this.chamber = value;

                    this.FetchResults();
                }
            }
        }

        /// <summary>
        /// Gets or sets the congress number (105–111)
        /// </summary>
        public int CongressNumber 
        { 
            get
            {
                return this.congressNumber;
            }

            set
            {
                if (this.congressNumber != value)
                {
                    this.congressNumber = value;

                    this.FetchResults();
                }
            }
        }

        /// <summary>Gets or sets the bill type</summary>
        /// <remarks>
        /// When type = introduced, the introduced_date determines the set of recent bills. 
        /// When type = updated, the latest_major_action_date determines the result set. See the sample 
        /// responses for examples of bill summary data.
        /// </remarks>
        public BillType BillType
        {
            get
            {
                return this.billType;
            }

            set
            {
                if (this.billType != value)
                {
                    this.billType = value;

                    this.FetchResults();
                }
            }
        }

        /// <summary>
        /// Gets the collection of bills
        /// </summary>
        public ObservableCollection<Bill> Bills { get; private set; }

        #endregion

        /// <summary>
        /// determines whether the state is valid to fetch results
        /// </summary>
        /// <returns>true if the CongressNumber is greater than 0</returns>
        public override bool ShouldFetchResults()
        {
            return this.CongressNumber > 0;
        }

        /// <summary>
        /// Clear the recent bills
        /// </summary>
        public override void ClearResults()
        {
            this.Bills.Clear();
        }

        /// <summary>
        /// Generate the REST URL
        /// </summary>
        /// <param name="baseUri">the base URI</param>
        /// <returns>the service URL</returns>
        [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Not relevant for Silverlight.")]
        public override Uri GenerateUrl(string baseUri)
        {
            var uriString = string.Format(
                CultureInfo.InvariantCulture,
                "{0}/{1}/{2}/bills/{3}.xml?api-key={4}",
                baseUri,
                this.CongressNumber,
                this.Chamber.ToString().ToLower(CultureInfo.InvariantCulture),
                this.BillType.ToString().ToLower(CultureInfo.InvariantCulture),
                this.ApiKey);

            return new Uri(uriString, UriKind.Absolute);
        }

        /// <summary>
        /// parse the results
        /// </summary>
        /// <param name="results">the results XML element</param>
        public override void OnParseResults(XElement results)
        {
            if (results == null)
            {
                throw new ArgumentNullException("results");
            }

            int congress = int.Parse(results.Element("congress").Value, CultureInfo.InvariantCulture);

            var bills = from bill in results.Element("bills").Elements("bill")
                        select new Bill(bill, congress);

            foreach (var bill in bills)
            {
                this.Bills.Add(bill);
            }
        }
    }
}
